import 'package:flutter/material.dart';
import 'package:flutter_common/util/context_extension.dart';

bool occurErr = false;

///方式一：
///```dart
///void main() {
///   runApp(MyApp());
///}
///class MyApp extends FxMaterialApp {
///
///   @override
///   Widget buildMaterialApp(GlobalKey<NavigatorState> navigatorKey) {
///     return MaterialApp(
///       navigatorKey: navigatorKey,
///       ...
///     );
///   }
///
///   @override
///   void handlerExceptionMessage(String msg) {
///     //report msg to server or to do something
///   }
///
/// }
///```
///方式二： 该方法需配合[navigatorKey]使用
///```dart
///void main() {
///   runApp(MyApp()); //MyApp must is StatefulWidget
///}
///
///class MyState extends State<MyApp> {
///
///   @override
///   void initState() {
///     super.initState();
///
///     initErrorReport(navigatorKey, (msg){
///       //report msg to server or to do something
///     });
///   }
///   @override
///   Widget build(BuildContext context) {
///     return MaterialApp(
///       navigatorKey: navigatorKey,
///       ...
///   }
///}
///```
/// [showErrorUI] 是否弹出错误提示框
///
initErrorReport(GlobalKey<NavigatorState> globalKey, Function(String) onError, [bool showErrorUI = true]) {
  ErrorWidget.builder = (FlutterErrorDetails e) => _ErrorReportWidget(e, onError);

  FlutterError.onError = (FlutterErrorDetails e) {
    if (!showErrorUI) {
      /// 正式环境就不需要弹出异常，影响体验,仅仅上报错误即可
      String error = "${e.exception}\n${e.stack ?? ""}";
      onError(error);
      return;
    }
    String emsg = e.exception.toString();
    String stack = e.stack.toString();
    if (emsg.startsWith("A RenderFlex overflowed by")) {
      //不展示边界超出的问题
      return;
    }
    if (emsg.contains("event is! RawKeyDownEvent || _keysPressed.isNotEmpty")) {
      //不展示pad外接键盘问题
      print("crash=====$emsg");
      return;
    }
    if("image resource service" == e.library) {
      //忽略第三方控件“cached_network_image”的错误
      print("crash=====$emsg");
      return;
    }
    // if(emsg.startsWith("Exception: Invalid image data")) {
    //   //第三方控件“cached_network_image”，遇过不存在的链接会抛异常，并且不能捕获，只能这边拦截处理了
    //   print("event=====$emsg");
    //   return;
    // }
    if (stack.contains("hardware_keyboard.dart")) {
      //不展示pad外接键盘问题
      print("crash=====$stack");
      return;
    }
    if (occurErr) return;
    occurErr = true;

    //解决 '!navigator._debugLocked‘: is not true.
    Future.delayed(const Duration(seconds: 1), () {
      occurErr = false;
      BuildContext context = globalKey.currentContext!;
      Navigator.push(context, FadePageRoute(_ErrorReportWidget(e, onError), opaque: false));
    });
  };
}

/// 展示全局错误信息
class _ErrorReportWidget extends StatelessWidget {
  late final String _errMsg;
  final Function(String) onError;

  _ErrorReportWidget(FlutterErrorDetails details, this.onError) {
    debugPrint(details.toString());
    String error = "${details.library}\n${details.exception}\n${details.stack ?? ""}";

    bool showLog = false;
    assert(showLog = true);
    if (showLog) print(error);

    _errMsg = error;
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        child: Material(
            type: MaterialType.transparency, child: _buildDialogPage(context)),
        onWillPop: () async {
          onError(_errMsg);
          return true;
        });
  }

  Widget _buildDialogPage(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 60),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(12.0),
        color: Colors.black.withOpacity(0.85),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
              padding: const EdgeInsets.only(bottom: 8),
              child: const Text(
                'Error',
                textScaleFactor: 1.15,
                style: TextStyle(
                    fontSize: 20,
                    fontWeight: FontWeight.w600,
                    color: Colors.red),
              )),
          SizedBox(
            height: MediaQuery.of(context).size.height - 280,
            // constraints: BoxConstraints(
            //     maxHeight: MediaQuery.of(context).size.height - 150),
            child: SingleChildScrollView(
              physics: const BouncingScrollPhysics(),
              child: Text(_errMsg,
                  style: const TextStyle(
                    fontSize: 12,
                    color: Colors.white,
                    fontWeight: FontWeight.w500,
                  ),
              ),
            ),
          ),
          Center(
            heightFactor: 1.5,
              child: FloatingActionButton(
                  child: const Text("关闭"),
                  onPressed: () {
                    onError(_errMsg);
                    Navigator.pop(context);
                  })),
        ],
      ),
    );
  }

  _buildOldPage(BuildContext context) {
    return WillPopScope(
        child: Stack(
          alignment: Alignment.center,
          children: [
            Container(
              color: Colors.white,
            ),
            SingleChildScrollView(
              padding: const EdgeInsets.only(top: 90),
              child: Text(
                _errMsg,
                style: const TextStyle(fontSize: 10, color: Colors.red),
              ),
            ),
            Positioned(
              bottom: 48,
              child: FloatingActionButton(
                  child: const Text("返回"),
                  onPressed: () {
                    onError(_errMsg);
                    Navigator.pop(context);
                  }),
            )
          ],
        ),
        onWillPop: () async {
          onError(_errMsg);
          return true;
        });
  }
}